package com.dsteiner.gwt.cafeteriasophia.client.controller;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import java.util.List;

import com.dsteiner.gwt.cafeteriasophia.client.ChangeWidget;
import com.dsteiner.gwt.cafeteriasophia.client.ChangeWidget.ChangeModel;
import com.dsteiner.gwt.cafeteriasophia.client.domain.Change;
import com.dsteiner.gwt.cafeteriasophia.client.domain.Product;
import com.dsteiner.gwt.cafeteriasophia.client.domain.Purchase;
import com.dsteiner.gwt.cafeteriasophia.client.domain.Sale;
import com.dsteiner.gwt.cafeteriasophia.client.domain.Stock;
import com.dsteiner.gwt.cafeteriasophia.client.event.ChangesEvent;
import com.dsteiner.gwt.cafeteriasophia.client.event.CheckShiftChangeEvent;
import com.dsteiner.gwt.cafeteriasophia.client.model.ProductModel;
import com.dsteiner.widgets.client.JsUtil;
import com.dsteiner.widgets.client.ObjectUtil;
import com.dsteiner.widgets.client.StringUtil;
import com.dsteiner.widgets.client.Widgets.ButtonExt;
import com.dsteiner.widgets.client.Widgets.HTMLExt;
import com.dsteiner.widgets.client.Widgets.HorizontalPanelExt;
import com.dsteiner.widgets.client.Widgets.IButton;
import com.dsteiner.widgets.client.Widgets.IHTML;
import com.dsteiner.widgets.client.Widgets.ILazyWidget;
import com.dsteiner.widgets.client.Widgets.IWidget;
import com.dsteiner.widgets.client.Widgets.WidgetListenerAdapter;
import com.dsteiner.widgets.client.controller.PopupOverlayController;
import com.dsteiner.widgets.client.event.EventListener;
import com.dsteiner.widgets.client.event.EventManager;
import com.dsteiner.widgets.client.event.EventManagerImpl;
import com.dsteiner.widgets.client.model.PrefilledTextBoxModel;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Widget;

public class ChangeController {

	private ChangeModel changeModel;
	private IHTML infoHtml;
	private PrefilledTextBoxModel stockTextBoxModel;
	private IButton addSalesButton;
	private IButton addPurchasesButton;
	private PrefilledTextBoxModel addSalesTextBoxModel;
	private IWidget addSalesPanel;
	protected ChangesEvent event;
	private IWidget addPurchasesPanel;
	private PrefilledTextBoxModel addPurchasesTextBoxModel;
	private IWidget addPurchasePricePanel;

	public void registerAddPurchasesButton(IButton addPurchasesButton) {
		this.addPurchasesButton = addPurchasesButton;
		addPurchasesButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				ProductModel productModel = changeModel.getProductModel();
				Purchase newPurchase = new Purchase();
				newPurchase.setRegisteredDate(new Date());
				newPurchase.setAmount(Math.abs(changeModel.getChange().getAmount()));
				if(addPurchasesTextBoxModel.isEdited())
					newPurchase.setPrice(new Double(addPurchasesTextBoxModel.getText()));
				newPurchase.setProduct(productModel.getProduct());
				productModel.addPurchase(newPurchase);
				EventManagerImpl.getInstance().fireEvent(new CheckShiftChangeEvent());
			}
		});
	}

	public void registerAddPurchasesPanel(IWidget addPurchasesPanel) {
		this.addPurchasesPanel = addPurchasesPanel;
	}

	public void registerAddPurchasesPricePanel(IWidget addPurchasePricePanel) {
		this.addPurchasePricePanel = addPurchasePricePanel;
	}

	public void registerAddPurchasesTextBoxModel(final PrefilledTextBoxModel addPurchasesTextBoxModel) {
		this.addPurchasesTextBoxModel = addPurchasesTextBoxModel;
		addPurchasesTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				if(!addPurchasesTextBoxModel.hasFocus() && addPurchasesTextBoxModel.isEdited()){
					String text = addPurchasesTextBoxModel.getText();
					if(!ObjectUtil.isDouble(text)){
						JsUtil.getInstance().showAlert("ingrese un numero (por ejemplo 4.0)");
						addPurchasesTextBoxModel.setText(changeModel.getProductModel().getProduct().getCost()+"");
						return;
					}
				}
			}
		});
	}

	public void registerAddSalesButton(IButton addSalesButton) {
		this.addSalesButton = addSalesButton;
		addSalesButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				ProductModel productModel = changeModel.getProductModel();
				Sale newSale = new Sale();
				newSale.setRegisteredDate(new Date());
				newSale.setAmount(Math.abs(changeModel.getChange().getAmount()));
				newSale.setPrice(new Double(addSalesTextBoxModel.getText()));
				newSale.setProduct(productModel.getProduct());
				productModel.addSale(newSale);
				EventManagerImpl.getInstance().fireEvent(new CheckShiftChangeEvent());
			}
		});
	}

	public void registerAddSalesPanel(IWidget addSalesPanel) {
		this.addSalesPanel = addSalesPanel;
	}

	public void registerAddSalesTextBoxModel(final PrefilledTextBoxModel addSalesTextBoxModel) {
		this.addSalesTextBoxModel = addSalesTextBoxModel;
		addSalesTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				if(!addSalesTextBoxModel.hasFocus() && addSalesTextBoxModel.isEdited()){
					String text = addSalesTextBoxModel.getText();
					if(!ObjectUtil.isDouble(text)){
						JsUtil.getInstance().showAlert("ingrese un numero (por ejemplo 4.0)");
						addSalesTextBoxModel.setText(changeModel.getProductModel().getProduct().getDefaultPrice()+"");
						return;
					}
				}
			}
		});
	}

	public void registerChangeModel(ChangeModel changeModel) {
		this.changeModel = changeModel;
	}

	public void registerChangeWidget(ILazyWidget changeWidget) {
		changeWidget.addWidgetListener(new WidgetListenerAdapter(){
			@Override
			public void onAttach(IWidget widget) {
				updateInfoHtml();
			}
		});
	}

	public void registerInfoHtml(IHTML infoHtml) {
		this.infoHtml = infoHtml;
	}

	public void registerStockTextBoxModel(final PrefilledTextBoxModel stockTextBoxModel) {
		this.stockTextBoxModel = stockTextBoxModel;
		stockTextBoxModel.addPropertyChangeListener("hasFocus", new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent evt) {
				if(!stockTextBoxModel.hasFocus() && stockTextBoxModel.isEdited()){
					ProductModel productModel = changeModel.getProductModel();
					String text = stockTextBoxModel.getText();
					if(stockTextBoxModel.isEdited() && !ObjectUtil.isDouble(text)){
						JsUtil.getInstance().showAlert("ingrese un numero (por ejemplo 4.0)");
						stockTextBoxModel.setText(null);
						return;
					}
					Stock stock = new Stock();
					stock.setAmount(stockTextBoxModel.isEdited() ? new Double(text) : 0);
					stock.setProduct(productModel.getProduct());
					productModel.setStock(stock);
					EventManagerImpl.getInstance().fireEvent(new CheckShiftChangeEvent());
				}
			}
		});
	}

	private void updateInfoHtml() {
		Change change = changeModel.getChange();
		ProductModel productModel = changeModel.getProductModel();
		String metric = change.getProduct().getMetric();
		StringBuffer html = new StringBuffer().append("<strong>"+change.getProduct().getName() 
				+ "</strong> con diferencia de " + change.getAmount() + " " 
				+(metric != null ? metric : "Q"));
		html.append(" (ingresado con ");
		ShiftChangeInfoController.addStock(html, productModel.getStock());
		html.append(", ");
		Product product = productModel.getProduct();
		if(product.isSaleable()){
			ShiftChangeInfoController.addSales(html, productModel.getSales());
			html.append(", ");
		}
		ShiftChangeInfoController.addPurchases(html, productModel.getPurchases());
		html.append(")");
		html.append("<br>Elige uno de los siguientes acciones:<br>");
		infoHtml.setHTML(html.toString());
		
		Change moneyChange = changeModel.getMoneyChange();
		
		addSalesPanel.setVisible(change.getProduct().isSaleable() && change.getAmount() < 0 
				&& moneyChange != null && moneyChange.getAmount() > 0);
		addSalesButton.setHTML("agregar "+Math.abs(change.getAmount())+" a las ventas");
		addSalesTextBoxModel.setText(change.getProduct().getDefaultPrice()+"");
		
		addPurchasesPanel.setVisible(!product.equals(Product.dinero) && change.getAmount() > 0 || 
				product.equals(Product.dinero) && change.getAmount() < 0);
		addPurchasesButton.setHTML("agregar "+Math.abs(change.getAmount())+" a las compras");
		Double cost = change.getProduct().getCost();
		addPurchasesTextBoxModel.setText(cost != null ? cost+"" : null);
		addPurchasePricePanel.setVisible(cost != null);
	}

}
